package com.wanxi.education.service.security;

import com.wanxi.education.model.vo.user.LoginVo;
import com.wanxi.education.model.vo.user.UserVO;
import com.wanxi.education.service.LoginService;
import com.wanxi.education.service.UserLoginService;
import com.wanxi.education.util.JwtTokenUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: zhe
 * @Date: 2021/9/25 13:44
 * @Description: 登录Token生成
 * @Version: 1.0
 */
@Service
public class UserLoginServiceImpl implements UserLoginService {

    //    登录标识 0:管理员 1：机构负责人 2：学员 -1:未知
//    private static Integer STATE = -1;

    @Value("${jwt.tokenHead}")
    String tokenHead;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private LoginService loginService;

    /**
     * 管理员电话号码密码登录认证
     *
     * @param loginVo
     * @return
     */
    @Override
    public Map<String, String> LoginPass(LoginVo loginVo) {
        Map<String, String> data = new HashMap<>();
//        登录标识 0:管理员 1：机构负责人 2：学员 -1:未知
        Integer state = 0;
        String token = null;
        try {
            token = toLoginPass(loginVo, state);
        } catch (Exception e) {
            e.printStackTrace();
            data.put("message", "手机号或密码错误");
            return data;
        }
        if (StringUtils.isEmpty(token)) {
            data.put("message", "手机号或密码错误");
            return data;
        }
        data.put("tokenHead", tokenHead);
        data.put("access_token", token);
        return data;
    }

    /**
     * 机构负责人手机号密码登录
     *
     * @param loginVo
     * @return
     */
    @Override
    public Map<String, String> bUserAccountLoginPass(LoginVo loginVo) {
        Map<String, String> data = new HashMap<>();
        //        登录标识 0:管理员 1：机构负责人 2：学员 -1:未知
        Integer state = 1;
        String token = null;
        try {
            token = toLoginPass(loginVo, state);
        } catch (Exception e) {
            e.printStackTrace();
            data.put("message", "手机号或密码错误");
            return data;
        }
        if (StringUtils.isEmpty(token)) {
            data.put("message", "手机号或密码错误");
            return data;
        }
        data.put("tokenHead", tokenHead);
        data.put("access_token", token);
        return data;
    }

    /**
     * 机构负责人手机号验证码登录
     *
     * @param loginVo
     * @return
     */
    @Override
    public Map<String, String> bUserAccountLoginCode(LoginVo loginVo) {
        Map<String, String> data = new HashMap<>();
        //        登录标识 0:管理员 1：机构负责人 2：学员 -1:未知
        Integer state = 1;
        String token = null;
        try {
            token = toLoginCode(loginVo, state);
        } catch (Exception e) {
            e.printStackTrace();
            data.put("message", "手机号输入有误");
            return data;
        }
        if (StringUtils.isEmpty(token)) {
            data.put("message", "手机号输入有误");
            return data;
        }
        data.put("tokenHead", tokenHead);
        data.put("access_token", token);
        return data;
    }

    /**
     * 学员手机号密码登录
     *
     * @param loginVo
     * @return
     */
    @Override
    public Map<String, String> cUserAccountLoginPass(LoginVo loginVo) {
        Map<String, String> data = new HashMap<>();
        //        登录标识 0:管理员 1：机构负责人 2：学员 -1:未知
        Integer state = 2;
        String token = null;
        try {
            token = toLoginPass(loginVo, state);
        } catch (Exception e) {
            e.printStackTrace();
            data.put("message", "手机号或密码错误");
            return data;
        }
        if (StringUtils.isEmpty(token)) {
            data.put("message", "手机号或密码错误");
            return data;
        }
        data.put("tokenHead", tokenHead);
        data.put("access_token", token);
        return data;
    }

    /**
     * 学员手机号验证码登录
     * @param loginVo
     * @return
     */
    @Override
    public Map<String, String> cUserAccountLoginCode(LoginVo loginVo) {
        Map<String, String> data = new HashMap<>();
        //        登录标识 0:管理员 1：机构负责人 2：学员 -1:未知
        Integer state = 2;
        String token = null;
        try {
            token = toLoginCode(loginVo, state);
        } catch (Exception e) {
            e.printStackTrace();
            data.put("message", "手机号输入有误");
            return data;
        }
        if (StringUtils.isEmpty(token)) {
            data.put("message", "手机号输入有误");
            return data;
        }
        data.put("tokenHead", tokenHead);
        data.put("access_token", token);
        return data;
    }

    /**
     * 电话号码和密码登录认证获取Token
     * @param loginVo 获取的登录信息
     * @param state   0:管理员 1：机构负责人 2：学员
     * @return
     */
    private String toLoginPass(LoginVo loginVo, Integer state) {
        String username = loginVo.getPhone();
        Assert.notNull(username, "手机号必须不能为空");
        String password = loginVo.getPassword();
        Assert.notNull(password, "密码必须不能为空");
//        UserVO userVO = findByPhone(username);
        UserVO userVO = loginService.findByPhone(username,state);
        if (userVO == null) {
            throw new UsernameNotFoundException("账户不存在");
        }
        boolean matches = passwordEncoder.matches(password, userVO.getPassword());
        if (matches) { //success
           /* switch (state) {
                case 0: // 管理员/超管
                    session.setAttribute("loginId", userVO.getId());
                    session.setAttribute("loginPhone", userVO.getPhone());
                    session.setAttribute("loginName", userVO.getUsername());
                    break;
                case 1: //机构负责人
                    session.setAttribute("loginBId", userVO.getId());
                    session.setAttribute("loginBPhone", userVO.getPhone());
                    session.setAttribute("loginBName", userVO.getUsername());
                    break;
                case 2: // 学员
                    session.setAttribute("loginCId", userVO.getId());
                    session.setAttribute("loginCPhone", userVO.getPhone());
                    session.setAttribute("loginCName", userVO.getUsername());
                    break;
                default:
                    break;
            }*/
            userVO.setState(state);
            return jwtTokenUtil.generateToken(userVO);
        }
        return null;
    }

    /**
     * 电话号码和验证码登录认证获取Token
     *
     * @param loginVo 获取的登录信息
     * @param state   0:管理员 1：机构负责人 2：学员
     * @return
     */
    private String toLoginCode(LoginVo loginVo, Integer state) {
        String username = loginVo.getPhone();
        Assert.notNull(username, "手机号必须不能为空");
        UserVO userVO = loginService.findByPhone(username,state);
        if (userVO == null) {
            throw new UsernameNotFoundException("账户不存在");
        }
        if (userVO.getId() > 0) { //success
            /*HttpSession session = request.getSession();
            switch (state) {
                case 0:
                    session.setAttribute("loginId", userVO.getId());
                    session.setAttribute("loginPhone", userVO.getPhone());
                    session.setAttribute("loginName", userVO.getUsername());
                    break;
                case 1:
                    session.setAttribute("loginBId", userVO.getId());
                    session.setAttribute("loginBPhone", userVO.getPhone());
                    session.setAttribute("loginBName", userVO.getUsername());
                    break;
                case 2:
                    session.setAttribute("loginCId", userVO.getId());
                    session.setAttribute("loginCPhone", userVO.getPhone());
                    session.setAttribute("loginCName", userVO.getUsername());
                    break;
                default:
                    break;
            }*/
            userVO.setState(state);
            return jwtTokenUtil.generateToken(userVO);
        }
        return null;
    }

    /**
     * 模拟数据库交互数据
     *
     * @param phone
     * @return
     */
    private UserVO findByPhone(String phone) {
        if (phone.equals("158299123")) {
            UserVO userVO = UserVO.builder()
                    .id(1L)
                    .username("张三")
                    .phone("158299123")
                    .password("123456").build();
            return userVO;
        }
        return null;
    }

}
